﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using InterfazGrafico.LibreriaClases.Clases;
using InterfazGrafico.LibreriaConstantes;
using InterfazGrafico.LibreriaConstantes.Elementos;

namespace InterfazGrafico.LibreriaClases.Propiedades
{
    /// <summary>
    /// Almacena las propiedades de un elemento específico.
    /// </summary>
    public class PTransformarCondicional : Propiedades
    {
        /// <summary>
        /// Entrada de datos.
        /// </summary>
        public string Entrada
        {
            get
            {
                return this.getPropiedadString(CTransformarCondicional.Entrada);
            }
            set
            {
                this.setOrAddPropiedad(CTransformarCondicional.Entrada, value);
            }
        }

        /// <summary>
        /// Salida de datos.
        /// </summary>
        public string Salida
        {
            get
            {
                return this.getPropiedadString(CTransformarCondicional.Salida);
            }
            set
            {
                this.setOrAddPropiedad(CTransformarCondicional.Salida, value);
            }
        }

        /// <summary>
        /// Estructura de entrada.
        /// </summary>
        public string EstructuraEntrada
        {
            get
            {
                return this.getPropiedadString(CTransformarCondicional.EstructuraEntrada);
            }
            set
            {
                this.setOrAddPropiedad(CTransformarCondicional.EstructuraEntrada, value);
            }
        }

        /// <summary>
        /// Estructura de salida.
        /// </summary>
        public string EstructuraSalida
        {
            get
            {
                return this.getPropiedadString(CTransformarCondicional.EstructuraSalida);
            }
            set
            {
                this.setOrAddPropiedad(CTransformarCondicional.EstructuraSalida, value);
            }
        }

        /// <summary>
        /// Lista de condiciones.
        /// </summary>
        public List<string> ListaCondiciones
        {
            get
            {
                return this.getPropiedadListaString(CTransformarCondicional.Condiciones);
            }
            set
            {
                this.setOrAddPropiedad(CTransformarCondicional.Condiciones, value);
            }
        }

        /// <summary>
        /// Lista de campos sobre los que aplicar condiciones.
        /// </summary>
        public List<string> ListaCamposCondiciones
        {
            get
            {
                return this.getPropiedadListaString(CTransformarCondicional.CamposCondiciones);
            }
            set
            {
                this.setOrAddPropiedad(CTransformarCondicional.CamposCondiciones, value);
            }
        }

        /// <summary>
        /// Lista de parámetros de las condiciones.
        /// </summary>
        public List<List<string>> ListaParametrosCondiciones
        {
            get
            {
                return this.getPropiedadListaListaString(CTransformarCondicional.ParametrosCondiciones);
            }
            set
            {
                this.setOrAddPropiedad(CTransformarCondicional.ParametrosCondiciones, value);
            }
        }

        /// <summary>
        /// Lista de funciones para cuando se cumple la condición.
        /// </summary>
        public List<string> ListaFuncionesVerdadero
        {
            get
            {
                return this.getPropiedadListaString(CTransformarCondicional.FuncionesVerdadero);
            }
            set
            {
                this.setOrAddPropiedad(CTransformarCondicional.FuncionesVerdadero, value);
            }
        }

        /// <summary>
        /// Lista de campos origen a los que aplica las funciones para cuando se cumple la condición.
        /// </summary>
        public List<string> ListaCamposOrigenVerdadero
        {
            get
            {
                return this.getPropiedadListaString(CTransformarCondicional.CamposOrigenVerdadero);
            }
            set
            {
                this.setOrAddPropiedad(CTransformarCondicional.CamposOrigenVerdadero, value);
            }
        }

        /// <summary>
        /// Lista de campos destino a los que aplica las funciones para cuando se cumple la condición.
        /// </summary>
        public List<string> ListaCamposDestinoVerdadero
        {
            get
            {
                return this.getPropiedadListaString(CTransformarCondicional.CamposDestinoVerdadero);
            }
            set
            {
                this.setOrAddPropiedad(CTransformarCondicional.CamposDestinoVerdadero, value);
            }
        }

        /// <summary>
        /// Lista de parámetros de las funciones para cuando se cumple la condición.
        /// </summary>
        public List<List<string>> ListaParametrosVerdadero
        {
            get
            {
                return this.getPropiedadListaListaString(CTransformarCondicional.ParametrosVerdadero);
            }
            set
            {
                this.setOrAddPropiedad(CTransformarCondicional.ParametrosVerdadero, value);
            }
        }

        /// <summary>
        /// Lista de funciones para cuando no se cumple la condición.
        /// </summary>
        public List<string> ListaFuncionesFalso
        {
            get
            {
                return this.getPropiedadListaString(CTransformarCondicional.FuncionesFalso);
            }
            set
            {
                this.setOrAddPropiedad(CTransformarCondicional.FuncionesFalso, value);
            }
        }

        /// <summary>
        /// Lista de campos origen a los que aplica las funciones para cuando no se cumple la condición.
        /// </summary>
        public List<string> ListaCamposOrigenFalso
        {
            get
            {
                return this.getPropiedadListaString(CTransformarCondicional.CamposOrigenFalso);
            }
            set
            {
                this.setOrAddPropiedad(CTransformarCondicional.CamposOrigenFalso, value);
            }
        }

        /// <summary>
        /// Lista de campos destino a los que aplica las funciones para cuando no se cumple la condición.
        /// </summary>
        public List<string> ListaCamposDestinoFalso
        {
            get
            {
                return this.getPropiedadListaString(CTransformarCondicional.CamposDestinoFalso);
            }
            set
            {
                this.setOrAddPropiedad(CTransformarCondicional.CamposDestinoFalso, value);
            }
        }

        /// <summary>
        /// Lista de parámetros de las funciones para cuando no se cumple la condición.
        /// </summary>
        public List<List<string>> ListaParametrosFalso
        {
            get
            {
                return this.getPropiedadListaListaString(CTransformarCondicional.ParametrosFalso);
            }
            set
            {
                this.setOrAddPropiedad(CTransformarCondicional.ParametrosFalso, value);
            }
        }

        /// <summary>
        /// Constructor por defecto.
        /// </summary>
        public PTransformarCondicional()
            : base()
        {
        }

        /// <summary>
        /// Obtiene los parámetros a partir del fichero XML indicado.
        /// </summary>
        /// <param name="fichero">Fichero de configuración XML</param>
        override public void leer(string fichero)
        {
            base.leer(fichero);
            XmlDocument xml = LeerXml.AbrirFicheroParametros(fichero);

            try
            { this.Entrada = LeerXml.ObtenerValorCampo(xml, CTransformarCondicional.RutaEntrada); }
            catch (Exception)
            { this.Entrada = string.Empty; }
            try
            { this.Salida = LeerXml.ObtenerValorCampo(xml, CTransformarCondicional.RutaSalida); }
            catch (Exception)
            { this.Salida = string.Empty; }
            try
            { this.EstructuraEntrada = LeerXml.ObtenerValorCampo(xml, CTransformarCondicional.RutaEstructuraEntrada); }
            catch (Exception)
            { this.EstructuraEntrada = string.Empty; }
            try
            { this.EstructuraSalida = LeerXml.ObtenerValorCampo(xml, CTransformarCondicional.RutaEstructuraSalida); }
            catch (Exception)
            { this.EstructuraSalida = string.Empty; }

            // Condiciones
            try
            {
                int numeroCondiciones = LeerXml.ObtenerNumeroNodosCampo(xml, CTransformarCondicional.RutaCondiciones);
                for (int indiceCondicion = 0; indiceCondicion < numeroCondiciones; indiceCondicion++)
                {
                    string condicion = string.Empty;
                    try
                    { condicion = LeerXml.ObtenerValorCampo(xml, CTransformarCondicional.RutaCondiciones, indiceCondicion, "./" + CTransformarCondicional.NodoCondicionesCondicionFuncion); }
                    catch (Exception)
                    { continue; }

                    if (!string.Empty.Equals(condicion))
                    {
                        this.ListaCondiciones.Add(condicion);

                        // Campo
                        string campo = string.Empty;
                        try
                        { campo = LeerXml.ObtenerValorCampo(xml, CTransformarCondicional.RutaCondiciones, indiceCondicion, "./" + CTransformarCondicional.NodoCondicionesCondicionCampo); }
                        catch (Exception)
                        { campo = string.Empty; }
                        this.ListaCamposCondiciones.Add(campo);

                        int numeroParametros = 0;
                        // Parametros
                        List<string> parametros = new List<string>();
                        try
                        {
                            numeroParametros = LeerXml.ObtenerNumeroNodosCampo(xml, CTransformarCondicional.RutaCondiciones, indiceCondicion, "./" + CTransformarCondicional.NodoCondicionesCondicionParametros);
                            for (int indiceParametro = 0; indiceParametro < numeroParametros; indiceParametro++)
                            {
                                string parametro = string.Empty;
                                try
                                { parametro = LeerXml.ObtenerValorCampo(xml, CTransformarCondicional.RutaCondiciones, indiceCondicion, "./" + CTransformarCondicional.NodoCondicionesCondicionParametros, indiceParametro); }
                                catch (Exception)
                                { parametro = string.Empty; }
                                parametros.Add(parametro);
                            }
                            this.ListaParametrosCondiciones.Add(parametros);
                        }
                        catch (Exception)
                        {
                            parametros = new List<string>();
                        }

                        // Funcion verdadero
                        string funcion = string.Empty;
                        try
                        { funcion = LeerXml.ObtenerValorCampo(xml, CTransformarCondicional.RutaCondiciones, indiceCondicion, CTransformarCondicional.NodoCondicionesCondicionFuncionVerdadero + "/" + CTransformarCondicional.NodoCondicionesCondicionFuncionFuncion); }
                        catch (Exception)
                        { funcion = string.Empty; }

                        this.ListaFuncionesVerdadero.Add(funcion);
                        // No hay función definida
                        if (string.Empty.Equals(funcion))
                        {
                            this.ListaCamposOrigenVerdadero.Add(null);
                            this.ListaCamposDestinoVerdadero.Add(null);
                            this.ListaParametrosVerdadero.Add(null);
                        }
                        // Hay función definida
                        else
                        {
                            string origen = string.Empty;
                            try
                            { origen = LeerXml.ObtenerValorCampo(xml, CTransformarCondicional.RutaCondiciones, indiceCondicion, CTransformarCondicional.NodoCondicionesCondicionFuncionVerdadero + "/" + CTransformarCondicional.NodoCondicionesCondicionFuncionOrigen); }
                            catch (Exception)
                            { origen = string.Empty; }
                            this.ListaCamposOrigenVerdadero.Add(origen);

                            string destino = string.Empty;
                            try
                            { destino = LeerXml.ObtenerValorCampo(xml, CTransformarCondicional.RutaCondiciones, indiceCondicion, CTransformarCondicional.NodoCondicionesCondicionFuncionVerdadero + "/" + CTransformarCondicional.NodoCondicionesCondicionFuncionDestino); }
                            catch (Exception)
                            { destino = string.Empty; }
                            this.ListaCamposDestinoVerdadero.Add(destino);

                            parametros = new List<string>();
                            try
                            {
                                numeroParametros = LeerXml.ObtenerNumeroNodosCampo(xml, CTransformarCondicional.RutaCondiciones, indiceCondicion, "./" + CTransformarCondicional.NodoCondicionesCondicionFuncionVerdadero + "/" + CTransformarCondicional.NodoCondicionesCondicionFuncionParametros);
                                for (int indiceParametro = 0; indiceParametro < numeroParametros; indiceParametro++)
                                {
                                    string parametro = string.Empty;
                                    try
                                    { parametro = LeerXml.ObtenerValorCampo(xml, CTransformarCondicional.RutaCondiciones, indiceCondicion, "./" + CTransformarCondicional.NodoCondicionesCondicionFuncionVerdadero + "/" + CTransformarCondicional.NodoCondicionesCondicionFuncionParametros, indiceParametro); }
                                    catch (Exception)
                                    { parametro = string.Empty; }
                                    parametros.Add(parametro);
                                }
                            }
                            catch (Exception)
                            { parametros = new List<string>(); }
                            this.ListaParametrosVerdadero.Add(parametros);
                        }

                        // Funcion falso
                        funcion = string.Empty;
                        try
                        { funcion = LeerXml.ObtenerValorCampo(xml, CTransformarCondicional.RutaCondiciones, indiceCondicion, CTransformarCondicional.NodoCondicionesCondicionFuncionFalso + "/" + CTransformarCondicional.NodoCondicionesCondicionFuncionFuncion); }
                        catch (Exception)
                        { funcion = string.Empty; }

                        this.ListaFuncionesFalso.Add(funcion);
                        // No hay función definida
                        if (string.Empty.Equals(funcion))
                        {
                            this.ListaCamposOrigenFalso.Add(null);
                            this.ListaCamposDestinoFalso.Add(null);
                            this.ListaParametrosFalso.Add(null);
                        }
                        // Hay función definida
                        else
                        {
                            string origen = string.Empty;
                            try
                            { origen = LeerXml.ObtenerValorCampo(xml, CTransformarCondicional.RutaCondiciones, indiceCondicion, CTransformarCondicional.NodoCondicionesCondicionFuncionFalso + "/" + CTransformarCondicional.NodoCondicionesCondicionFuncionOrigen); }
                            catch (Exception)
                            { origen = string.Empty; }
                            this.ListaCamposOrigenFalso.Add(origen);

                            string destino = string.Empty;
                            try
                            { destino = LeerXml.ObtenerValorCampo(xml, CTransformarCondicional.RutaCondiciones, indiceCondicion, CTransformarCondicional.NodoCondicionesCondicionFuncionFalso + "/" + CTransformarCondicional.NodoCondicionesCondicionFuncionDestino); }
                            catch (Exception)
                            { destino = string.Empty; }
                            this.ListaCamposDestinoFalso.Add(destino);

                            parametros = new List<string>();
                            try
                            {
                                numeroParametros = LeerXml.ObtenerNumeroNodosCampo(xml, CTransformarCondicional.RutaCondiciones, indiceCondicion, "./" + CTransformarCondicional.NodoCondicionesCondicionFuncionFalso + "/" + CTransformarCondicional.NodoCondicionesCondicionFuncionParametros);
                                for (int indiceParametro = 0; indiceParametro < numeroParametros; indiceParametro++)
                                {
                                    string parametro = string.Empty;
                                    try
                                    { parametro = LeerXml.ObtenerValorCampo(xml, CTransformarCondicional.RutaCondiciones, indiceCondicion, "./" + CTransformarCondicional.NodoCondicionesCondicionFuncionFalso + "/" + CTransformarCondicional.NodoCondicionesCondicionFuncionParametros, indiceParametro); }
                                    catch (Exception)
                                    { parametro = string.Empty; }
                                    parametros.Add(parametro);
                                }
                            }
                            catch (Exception)
                            { parametros = new List<string>(); }
                            this.ListaParametrosFalso.Add(parametros);
                        }
                    }
                }
            }
            catch (Exception)
            {
                this.ListaCondiciones = new List<string>();
                this.ListaFuncionesFalso = new List<string>();
                this.ListaFuncionesVerdadero = new List<string>();
                this.ListaCamposCondiciones = new List<string>();
                this.ListaCamposDestinoVerdadero = new List<string>();
                this.ListaCamposDestinoFalso = new List<string>();
                this.ListaCamposOrigenFalso = new List<string>();
                this.ListaCamposOrigenVerdadero = new List<string>();
                this.ListaParametrosCondiciones = new List<List<string>>();
                this.ListaParametrosFalso = new List<List<string>>();
                this.ListaParametrosVerdadero = new List<List<string>>();
            }
        }

        /// <summary>
        /// Escribe los parámetros al fichero XML indicado.
        /// </summary>
        /// <param name="fichero">Fichero de configuración XML</param>
        public override void escribir(string fichero)
        {
            try
            {
                base.escribir(fichero);
                XmlWriter xml = EscribirXml.AbrirFicheroParametros(fichero);
                EscribirXml.InicioElemento(xml, CTransformarCondicional.NodoRaiz);
                EscribirXml.EscribeNodo(xml, CTransformarCondicional.NodoEntrada, Entrada);
                EscribirXml.EscribeNodo(xml, CTransformarCondicional.NodoSalida, Salida);
                EscribirXml.EscribeNodo(xml, CTransformarCondicional.NodoEstructuraSalida, EstructuraSalida);
                EscribirXml.EscribeNodo(xml, CTransformarCondicional.NodoEstructuraEntrada, EstructuraEntrada);
                EscribirXml.InicioElemento(xml, CTransformarCondicional.NodoConfiguracion);
                // Condiciones
                EscribirXml.InicioElemento(xml, CTransformarCondicional.NodoCondiciones);
                int i = 0;
                foreach (string condicion in ListaCondiciones)
                {
                    // Condicion
                    EscribirXml.InicioElemento(xml, CTransformarCondicional.NodoCondicionesCondicion);
                    EscribirXml.EscribeNodo(xml, CTransformarCondicional.NodoCondicionesCondicionFuncion, condicion);
                    EscribirXml.EscribeNodo(xml, CTransformarCondicional.NodoCondicionesCondicionCampo, ListaCamposCondiciones[i]);
                    EscribirXml.InicioElemento(xml, CTransformarCondicional.NodoCondicionesCondicionParametros);
                    foreach (string parametro in ListaParametrosCondiciones[i])
                        EscribirXml.EscribeNodo(xml, CTransformarCondicional.NodoCondicionesCondicionParametrosParametro, parametro);
                    EscribirXml.FinElemento(xml);
                    // Función si verdadero
                    EscribirXml.InicioElemento(xml, CTransformarCondicional.NodoCondicionesCondicionFuncionVerdadero);
                    EscribirXml.EscribeNodo(xml, CTransformarCondicional.NodoCondicionesCondicionFuncionFuncion, ListaFuncionesVerdadero[i]);
                    EscribirXml.EscribeNodo(xml, CTransformarCondicional.NodoCondicionesCondicionFuncionOrigen, ListaCamposOrigenVerdadero[i]);
                    EscribirXml.EscribeNodo(xml, CTransformarCondicional.NodoCondicionesCondicionFuncionDestino, ListaCamposDestinoVerdadero[i]);
                    EscribirXml.InicioElemento(xml, CTransformarCondicional.NodoCondicionesCondicionFuncionParametros);
                    foreach (string parametro in ListaParametrosVerdadero[i])
                        EscribirXml.EscribeNodo(xml, CTransformarCondicional.NodoCondicionesCondicionFuncionParametrosParametro, parametro);
                    EscribirXml.FinElemento(xml);
                    EscribirXml.FinElemento(xml);
                    // Función si falso
                    EscribirXml.InicioElemento(xml, CTransformarCondicional.NodoCondicionesCondicionFuncionFalso);
                    EscribirXml.EscribeNodo(xml, CTransformarCondicional.NodoCondicionesCondicionFuncionFuncion, ListaFuncionesFalso[i]);
                    EscribirXml.EscribeNodo(xml, CTransformarCondicional.NodoCondicionesCondicionFuncionOrigen, ListaCamposOrigenFalso[i]);
                    EscribirXml.EscribeNodo(xml, CTransformarCondicional.NodoCondicionesCondicionFuncionDestino, ListaCamposDestinoFalso[i]);
                    EscribirXml.InicioElemento(xml, CTransformarCondicional.NodoCondicionesCondicionFuncionParametros);
                    foreach (string parametro in ListaParametrosFalso[i])
                        EscribirXml.EscribeNodo(xml, CTransformarCondicional.NodoCondicionesCondicionFuncionParametrosParametro, parametro);
                    EscribirXml.FinElemento(xml);
                    EscribirXml.FinElemento(xml);
                    EscribirXml.FinElemento(xml);
                    i++;
                }
                EscribirXml.FinElemento(xml);
                EscribirXml.FinElemento(xml);
                EscribirXml.FinElemento(xml);
                EscribirXml.Flush(xml);
                EscribirXml.Close(xml);
            }
            catch (Exception ex)
            {
                throw new ApplicationException(Constantes.ERROR_ESCRITURA_FICHERO_CONFIGURACION, ex);
            }
        }
    }
} 